package com.bbcare.followup.plat.task;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.bbcare.comm.AppException;
import com.bbcare.comm.Constants;
import com.bbcare.comm.DateUtil;
import com.bbcare.comm.SeqUtil;
import com.bbcare.followup.plat.entity.FollowQueue;
import com.bbcare.followup.plat.entity.PatientTask;
import com.bbcare.followup.plat.service.IPatientInfoHisService;
import com.bbcare.followup.plat.service.IPatientService;
import com.bbcare.followup.plat.store.ibatis.IConfCacheDAO;
import com.bbcare.followup.plat.store.ibatis.IFollowQueueDAO;

/**
 * @name: PtFollowUpTimeTaskSmsSendTask.java
 * @author: tao
 * @createTime: 2017年8月1日
 * @description: 根据随访时间 为规则给用户发送短信
 * 一、随访日期前一周推送一次提醒，每次随访仅1条短信提醒
 * 二、随访日前一周和随访日前一天，每次随访发送2条提醒短信
 * @modify:
 */
public class PtFollowUpTimeTaskSmsSendTask implements Job {
    private final Log logger = LogFactory.getLog(PtFollowUpTimeTaskSmsSendTask.class);

    @Autowired
    private IPatientInfoHisService ptHisService;

    @Autowired
    private IPatientService patientSerivce;

    @Autowired
    private IConfCacheDAO confCacheDao;

    @Autowired
    private IFollowQueueDAO queueDao;

    @Override
    public void execute(JobExecutionContext context) {
        logger.warn("job------start: PtFollowUpTimeTaskSmsSendTask--" + DateUtil.getMillSysDate());

        Map<String, Object> inRule = new HashMap<String, Object>();
        inRule.put("status", Constants.TABLE_RECORD_STATUS_NOMAL);
        inRule.put("queueStatus", Constants.QUEUE_STATUS_NOMAL);
        inRule.put("ruleType", Constants.FU_INFORM_RULE_SMS_SEND_RULE_TYPE_FOLLOWUP);//按随访时间发送
        //过滤不在发送时间内的规则
        String nowTime = DateUtil.getHm();
        inRule.put("nowTime", nowTime);

        List<Map<String, Object>> outRuleList = null;
        try {
            outRuleList = confCacheDao.listInformRuleByFollowUptime(inRule);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            logger.error("查发送规则信息报错", e1);
            return;
        }
        int totalNum = 0;
        if (!CollectionUtils.isEmpty(outRuleList)) {
            int outSize = outRuleList.size();
            int tp = 0;
            Map<String, Object> outMap = new HashMap<String, Object>();
            for (tp = 0; tp < outSize; tp++) {
                int beforeDay = 0;
                String queueId = "";
                String rangeTime = "";
                String templateType = "";
                String tenantId = "";
                String ruleId = "";
                String tempateId = "";
                String tempateContent = "";
                String informType = "";
                String sign = "";
                String scheduleFlag = "";
                Integer ageEndDay = null;
                outMap = outRuleList.get(tp);
                ruleId = (String) outMap.get("id");
//                beforeDay = (String)outMap.get("beforeDay");
                if (null == outMap.get("beforeDay")) {
                    logger.info("规则发送 提前日期为空cycleTime，跳出此规则  ruleId=" + ruleId);
                    continue;
                } else {
                    try {
                        beforeDay = Integer.parseInt("" + outMap.get("beforeDay"));
                        if (beforeDay > 0) {
                            //beforeDay 代表天   从当天开始往后算 +7==随访时间 或 +1 ==随访时间 则发短信
                            rangeTime = DateUtil.getDate_8(DateUtil.addDay(new Date(), beforeDay)); //
                        } else {
                            continue;
                        }
                    } catch (ParseException e) {
                        logger.error("转换时间报错 ruleId：" + ruleId, e);
                        continue;
                    }
                }
                queueId = (String) outMap.get("queueId");
                templateType = (String) outMap.get("templateType");
                tenantId = (String) outMap.get("tenantId");

                // 结束发送短信时间
                ageEndDay = (Integer) outMap.get("ageEndDay");

                tempateId = (String) outMap.get("templateId");
                tempateContent = (String) outMap.get("smsTemplate");
                informType = (String) outMap.get("informType");
                sign = (String) outMap.get("sign");
                scheduleFlag = (String) outMap.get("scheduleFlag");
                if (StringUtils.isEmpty(tempateContent)) {
                    logger.info("短信内容为空 跳出此规则 " + ruleId);
                    continue;
                }

                List<PatientTask> epList = new ArrayList<PatientTask>();
                Map<String, Object> paramIn = new HashMap<String, Object>();
                paramIn.put("informType", informType);//发送短信渠道
                paramIn.put("taskStatus", Constants.PATIENT_TASK_STATUS_INIT);// 未开始的任务
//                paramIn.put("currDay", DateUtil.getCurrDate());// 今日在窗口期内
                paramIn.put("templType", Constants.QUESTIONNAIRE_TYPE_0);// 含有门诊问卷
                paramIn.put("revSeqNo", Constants.TASK_SEQ_FOR_INIT);// 去掉建档任务
                paramIn.put("ruleStatus", Constants.TABLE_RECORD_STATUS_NOMAL);// 状态正常的提醒规则
//                paramIn.put("nowTime", DateUtil.getSysDate4Hms());// 当前时间是否在允许发送提醒的时间范围内
                paramIn.put("queueId", queueId);// 队列id
                paramIn.put("rangeTime", rangeTime);// 7天前 | 一天前是否发送过

                paramIn.put("templateType", templateType);// 模板类型
//                paramIn.put("sendStatus", Constants.PT_INFORM_SMS_STATUS_SUCCESS);// 过滤掉发送状态成功的 
                paramIn.put("opCode", Constants.OP_CODE_3002);
                paramIn.put("opType", Constants.OP_TYPE_BG_ADMIN);
                paramIn.put("taskType", Constants.TASK_TYPE_SCHEME_SCHEDULE);// 门诊任务
                paramIn.put("tenantId", tenantId);

                // 结束发短信时间
                paramIn.put("ageEndDay", ageEndDay);
//                paramIn.put("sendTime", sendTime); //短信发送时间   判断本次随访短信 是否已经发过 
                String authorId = Constants.BG_LOGIN_NO_ADMIN;// 后台程序处理工号
                String ipAddress = "";
                try {
                    InetAddress netAddress = InetAddress.getLocalHost();
                    ipAddress = netAddress.getHostAddress();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                    ipAddress = "";
                }

                String deptId = "";
                Map<String, Object> queueMapIn = new HashMap<String, Object>();
                queueMapIn.put("id", queueId);
                List<FollowQueue> fqList;
                try {
                    fqList = queueDao.selectById(queueMapIn);
                    if (!CollectionUtils.isEmpty(fqList)) {
                        FollowQueue fqVo = fqList.get(0);
                        deptId = fqVo.getDeptId();
                    } else {
                        logger.error("任务对应队列不存在! 队列ID[" + queueId + "]");
                        continue;
                    }
                } catch (Exception e2) {
                    logger.error("任务对应队列不存在! 队列ID[" + queueId + "]", e2);
                    continue;
                }

                int start = 0;
                int end = 100;
                while (true) {
                    try {
                        /*
                         * 1、随访日期前一天 或者 随访日期前一周  发送短信    暂用 cycleTime 该字段  
                         * 2、需要提取的是含有门诊问卷的任务，若是线上随访任务，则不需要提取，通过app提醒
                         * 3、配置了短信模板的队列才需要发送，未配置则不需要发送
                         */
                        epList.clear();
                        paramIn.put("start", start);
                        paramIn.put("end", end);// 每次提取100条
                        paramIn.put("ruleId", ruleId);
                        epList = ptHisService.getPatientFollowTimeList(paramIn);
                        
                        /*start+=100;
                        end=100;*/
                    } catch (Exception e) {
                        logger.error("根据规则查询符合条件任务失败", e);
                        return;
                    }
                    if (!CollectionUtils.isEmpty(epList)) {
                        Map<String, Object> dealIn = new HashMap<String, Object>();
                        PatientTask ptVo = new PatientTask();
                        int iep = epList.size();
                        int k = 0;
                        for (k = 0; k < iep; k++) {
                            dealIn.clear();
                            ptVo = epList.get(k);

                            dealIn.put("taskId", ptVo.getId());
                            dealIn.put("userId", ptVo.getUserId());
                            dealIn.put("taskName", ptVo.getTaskName());
                            dealIn.put("ptSchemeId", ptVo.getPtSchemeid());
                            dealIn.put("queueId", ptVo.getQueueId());
                            dealIn.put("authorId", authorId);
                            dealIn.put("updateTime", DateUtil.getTimeString(DateUtil.getSysDateA()));
                            dealIn.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));
                            dealIn.put("opCode", Constants.OP_CODE_3002);
                            dealIn.put("opType", Constants.OP_TYPE_BG_ADMIN);


                            //一个规则队列下  下面参数相同
                            dealIn.put("ipAddress", ipAddress);
                            dealIn.put("tenantId", tenantId);
                            dealIn.put("tempateId", tempateId);
                            dealIn.put("tempateContent", tempateContent);
                            dealIn.put("ruleId", ruleId);
                            dealIn.put("sign", sign);
                            dealIn.put("rangeTime", rangeTime);
                            dealIn.put("deptId", deptId);
                            dealIn.put("smsType", templateType);
                            dealIn.put("authorId", authorId);
                            dealIn.put("informType", informType);
                            dealIn.put("executeTime", ptVo.getExecuteTime());
                            dealIn.put("beforeDay", beforeDay);// 7天前 | 一天前是否发送过
                            dealIn.put("scheduleFlag", scheduleFlag);//是否需要根据排班安排具体随访时间
                            try {
                                if (null == ptVo.getExecuteTime()) {
                                    throw new AppException("0000001", "随访时间为空");
                                }
                                ptHisService.dealPatientFollowTimeSmsSend(dealIn);
                                totalNum++;
                            } catch (AppException e) {
                                logger.error("dealPatientFollowTimeSmsSend AppException...dealIn==" + dealIn.toString(), e);
                                // 将错误记录存在异常表pt_excp_rd中，后续查询过滤掉这批数据
                                try {
                                    dealIn.put("errMsg", e.getErrMsg());
                                    patientSerivce.savePtExcpInfo(dealIn);
                                } catch (Exception e1) {
                                    // TODO Auto-generated catch block
                                    logger.error("---savePtExcpInfo AppException---dealIn==" + dealIn.toString(), e);
                                    // 这里再报错，可能会出现死循环，后续补
                                }
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                logger.error("dealPatientFollowTimeSmsSend Exception...dealIn==" + dealIn.toString(), e);
                                e.printStackTrace();
                                // 将错误记录存在异常表pt_excp_rd中，后续查询过滤掉这批数据
                                try {
                                    dealIn.put("errMsg", "dealPatientWinTaskSmsSend Exception:" + e.getMessage());
                                    patientSerivce.savePtExcpInfo(dealIn);
                                } catch (Exception e1) {
                                    // TODO Auto-generated catch block
                                    logger.error("---savePtExcpInfo Exception---dealIn==" + dealIn.toString(), e);
                                }
                            }
                        }
                    } else {
                        // 无记录，返回
                        break;
                    }
                }
            }
        }

        logger.warn("---end: PtFollowUpTimeTaskSmsSendTask---total send sms==" + totalNum);

        return;
    }
}
